﻿/*
 * ASP.NET Validation Controls for MVC (using WebUIValidation.js)
 *
 * Copyright (c) 2009 Guramrit Singh Dhillon
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Classic.Mvc.Web.UI.Validators
{
    public class ValidationSummary : IMvcControl
    {
        private readonly object _htmlAttributes;
        public System.Web.UI.WebControls.ValidationSummaryDisplayMode DisplayMode { get; set; }
        public string ID { get; set; }
        public string Tooltip { get; set; }
        public string HeaderText { get; set; }
        public bool ShowMessageBox { get; set; }
        public bool ShowSummary { get; set; }
        public string ValidationGroup { get; set; }

        internal ValidationSummary(string id, object htmlAttributes)
        {
            ID = id;
            _htmlAttributes = htmlAttributes;
            DisplayMode = System.Web.UI.WebControls.ValidationSummaryDisplayMode.BulletList;
        }

        private readonly IDictionary<string, object> _scriptAttributes = new Dictionary<string, object>();

        string IMvcControl.GetScript()
        {
            _scriptAttributes.Clear();
            AddScriptAttributes();
            var script = new StringBuilder()
                .AppendLine(
                string.Format("var {0} = document.all ? document.all[\"{0}\"] : document.getElementById(\"{0}\")", ID));
            foreach (var scriptAttribute in _scriptAttributes)
            {
                script.AppendLine(string.Format("{0}.{1} = {2}", ID, scriptAttribute.Key, scriptAttribute.Value));
            }
            return script.ToString();
        }

        protected void RegisterScriptAttribute(string attributeName, string attributeValue, bool encode)
        {
            if (encode)
            {
                _scriptAttributes.Add(attributeName, "\"" + attributeValue + "\"");
            }
            else
            {
                _scriptAttributes.Add(attributeName, attributeValue);
            }
        }

        protected void RegisterScriptAttribute(string attributeName, string attributeValue)
        {
            RegisterScriptAttribute(attributeName, attributeValue, true);
        }


        protected virtual void AddScriptAttributes()
        {
            if (!string.IsNullOrEmpty(ValidationGroup))
                RegisterScriptAttribute("validationGroup", ValidationGroup);

            if (!string.IsNullOrEmpty(HeaderText))
                RegisterScriptAttribute("headertext", HeaderText);

            if (ShowMessageBox)
                RegisterScriptAttribute("showmessagebox", "True");

            if (!ShowSummary)
                RegisterScriptAttribute("showsummary", "False");

            if (DisplayMode != System.Web.UI.WebControls.ValidationSummaryDisplayMode.BulletList)
                RegisterScriptAttribute("displaymode", DisplayMode.ToString());
        }

        string IMvcControl.GetControlText()
        {
            var tagBuilder = new TagBuilder("div");
            tagBuilder.GenerateId(ID);
            tagBuilder.MergeAttribute("title", Tooltip);
            if (_htmlAttributes != null)
            {
                tagBuilder.MergeAttributes((from attr in _htmlAttributes.GetType().GetProperties()
                                            select new
                                                       {
                                                           attr.Name,
                                                           Value = attr.GetValue(_htmlAttributes, null)
                                                       })
                                               .ToDictionary(obj => obj.Name,
                                                             obj => obj.Value), true);
            }
            ID = tagBuilder.Attributes["id"];
            var _style =
                tagBuilder.Attributes.ContainsKey("style")
                    ? (from attr in tagBuilder.Attributes["style"].Split(';')
                       let attrs = attr.ToLowerInvariant().Split(':')
                       select new {Key = attrs[0].Trim(), Value = attrs[1].Trim()})
                          .ToDictionary(x => x.Key,
                                        x => x.Value)
                    : new Dictionary<string, string>();
            if (!_style.ContainsKey("color"))
                _style.Add("color", "red");

            if (_style.ContainsKey("display"))
                _style["display"] = "none";
            else
                _style.Add("display", "none");
            tagBuilder.MergeAttribute("style",
                                      string.Join(";", (from attr in _style
                                                        select attr.Key + ":" + attr.Value)
                                                           .ToArray()), true);
            return tagBuilder.ToString();
        }
    }
}